package com.nariano.webapp;

import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.rmi.server.UID;
import java.util.List;
import java.util.Map;
import java.util.Random;


import org.apache.wicket.Page;
import org.apache.wicket.Session;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.AjaxFallbackLink;
import org.apache.wicket.behavior.SimpleAttributeModifier;
import org.apache.wicket.markup.ComponentTag;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Button;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.PasswordTextField;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.markup.html.form.validation.EqualPasswordInputValidator;
import org.apache.wicket.markup.html.form.validation.FormComponentFeedbackBorder;
import org.apache.wicket.markup.html.image.Image;
import org.apache.wicket.markup.html.image.resource.DynamicImageResource;
import org.apache.wicket.markup.html.link.Link;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.markup.html.panel.Fragment;
import org.apache.wicket.model.CompoundPropertyModel;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.model.ResourceModel;
import org.apache.wicket.validation.IValidatable;
import org.apache.wicket.validation.validator.AbstractValidator;
import org.apache.wicket.validation.validator.EmailAddressValidator;
import org.apache.wicket.validation.validator.StringValidator.ExactLengthValidator;
import org.apache.wicket.validation.validator.StringValidator.LengthBetweenValidator;

import com.nariano.server.domain.engine.Engine;
import com.nariano.server.domain.entities.Area;
import com.nariano.server.domain.entities.City;
import com.nariano.server.domain.entities.User;
import com.nariano.server.services.cityservice.CityService;
import com.nariano.server.services.mapservice.MapService;
import com.nariano.server.services.userservice.UserService;
import com.nariano.server.utils.spring.SpringFactory;
import com.octo.captcha.service.image.DefaultManageableImageCaptchaService;
import com.octo.captcha.service.image.ImageCaptchaService;
import javax.imageio.ImageIO;

@SuppressWarnings("unused")
public class EditPlayerPage extends CreateCityPage {

    private transient UserService userService = SpringFactory.getBean("userService",
            UserService.class);
    private transient CityService cityService = SpringFactory.getBean("cityService",
    		CityService.class);

    
    public EditPlayerPage(){
        super();
    	City existingCity = null;
        if (NarianoSession.get().getUser() == null) 
        { 
            NarianoSession.get().setUser(new User());
        } else {
        	List<City> cities = cityService.getCities(NarianoSession.get().getUser());
        	if (cities.size()>0) {
        		existingCity = cities.iterator().next();
        	}
        }
        
        final User user = NarianoSession.get().getUser();
        final City city = existingCity==null ? new City() : existingCity;

        Form form = new Form("form");
        add(form);

        FeedbackPanel feedback = new FeedbackPanel("feedback");
        add(feedback);

        form.add(new FormComponentFeedbackBorder("border1").add(new TextField(
                "username", new PropertyModel(user, "userName")).setRequired(
                true).add(LengthBetweenValidator.lengthBetween(1, 32)).add(
                new UniqueUserNameValidator(user))));

        form.add(new FormComponentFeedbackBorder("border2").add(new TextField(
                "email", new PropertyModel(user, "email")).setRequired(true)
                .add(EmailAddressValidator.getInstance()).add(new UniqueEmailValidator(user))));

        TextField pwd1 = new PasswordTextField("password1", new PropertyModel(
                user, "passwordHashed")).setResetPassword(false);
        form.add(new FormComponentFeedbackBorder("border3").add(pwd1
                .setRequired(true)));
        TextField pwd2 = new PasswordTextField("password2", new PropertyModel(
                user, "passwordHashed")).setResetPassword(false);
        form.add(new FormComponentFeedbackBorder("border4").add(pwd2
                .setRequired(true)));
        form.add(new EqualPasswordInputValidator(pwd1, pwd2));
        
        form.add(new FormComponentFeedbackBorder("border5").add(new TextField(
                "cityname", new PropertyModel(city, "name")).setRequired(
                true).add(LengthBetweenValidator.lengthBetween(1, 30))));
                
        form.add(new Link("cancel", new ResourceModel("cancelText")) {

            @Override
            public void onClick() {
                setResponsePage(Index.class);
            }

        });

        form.add(new Button("submit", new ResourceModel("submitText")) {

            @Override
            public void onSubmit() {
                
                if (user.getId() == null) {
                    setResponsePage(new AddPlayerConfirmPage(user, city));
                } else {
                    NarianoSession.get().setUser(user);
                    userService.updateUser(user);
                    
                    if (city.getId()==null) {
                    	createCity(user,city);
                    } else {
                    	Area area = mapService.getArea(city.getLocation());
                    	area.getCity().setName(city.getName());
                    	mapService.updateAreas(area);
                    }
                    setResponsePage(Index.class);
                }
            }

        });


    }
    
    private String challengeId = null;

    private String challengeResponse;
    
    private DynamicImageResource getImageResource() {
        return new DynamicImageResource() {
            @Override
            protected byte[] getImageData() {
                ByteArrayOutputStream os = new ByteArrayOutputStream();
                challengeId = new UID().toString();
                BufferedImage image = SpringFactory.getBean("captchaService",
                        ImageCaptchaService.class).getImageChallengeForID(
                        challengeId, Session.get().getLocale());
                // Writing the image to outputstream
                try {
                    ImageIO.write(image, "png", os);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
                // flush it in the response
                return os.toByteArray();
            }
          };
    }

}

class UniqueUserNameValidator extends AbstractValidator {

    private final User user;

    UniqueUserNameValidator(User user) {
        this.user = user;
    }

    @Override
    protected void onValidate(IValidatable validatable) {
        if ((user.getId() == null || (user.getId() != null && !user
                .getUserName().equals((String) validatable.getValue())))
                && SpringFactory.getBean("userService", UserService.class)
                        .findUserFromUserName((String) validatable.getValue()) != null) {
            error(validatable);
        }
    }

    @Override
    protected String resourceKey() {
        return "UniqueUserNameValidator";
    }

    @Override
    protected Map variablesMap(IValidatable validatable) {
        Map map = super.variablesMap(validatable);
        map.put("username", validatable.getValue());
        return map;
    }
}

class UniqueEmailValidator extends AbstractValidator {

    private final User user;

    UniqueEmailValidator(User user) {
        this.user = user;
    }

    @Override
    protected void onValidate(IValidatable validatable) {
        if ((user.getId() == null || (user.getId() != null && !user
                .getEmail().equals((String) validatable.getValue())))
                && SpringFactory.getBean("userService", UserService.class)
                        .findUserFromEmail((String) validatable.getValue()) != null) {
            error(validatable);
        }
    }

    @Override
    protected String resourceKey() {
        return "UniqueEmailNameValidator";
    }

    @Override
    protected Map variablesMap(IValidatable validatable) {
        Map map = super.variablesMap(validatable);
        map.put("email", validatable.getValue());
        return map;
    }
    
   
}
